package com.bosssoft.platform.fasttcc.support.spring;

import com.bosssoft.platform.fasttcc.assist.TccMethodIntercepter;
import com.bosssoft.platform.fasttcc.support.OriginMethodInvoke;
import com.jfireframework.baseutil.TRACEID;
import com.jfireframework.baseutil.reflect.ReflectUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(1)
public class TccMethodEnHancer
{
    @Autowired
    private              TccMethodIntercepter tccMethodIntercepter;
    private static final Logger               logger = LoggerFactory.getLogger(TccMethodEnHancer.class);

    @Around("@annotation(com.bosssoft.platform.fasttcc.Tcc) || @annotation(com.bosssoft.platform.fasttcc.TccSimple)")
    public Object invoke(final ProceedingJoinPoint pjp) throws Throwable
    {

        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method          method    = signature.getMethod();
        String          traceId         = TRACEID.newTraceId();
        logger.debug("traceId:{} 拦截tcc方法:{}.{}",traceId,method.getDeclaringClass().getName(),signature.getName());
        Object[]        args      = pjp.getArgs();
        Object result = tccMethodIntercepter.onProcessTccMethod(method, args, new OriginMethodInvoke()
        {
            @Override
            public Object invoke()
            {
                try
                {
                    return pjp.proceed();
                }
                catch (Throwable e)
                {
                    ReflectUtil.throwException(e);
                    return null;
                }
            }
        });
        return result;
    }

    public TccMethodIntercepter getTccMethodIntercepter()
    {
        return tccMethodIntercepter;
    }

    public void setTccMethodIntercepter(TccMethodIntercepter tccMethodIntercepter)
    {
        this.tccMethodIntercepter = tccMethodIntercepter;
    }
}
